home *** CD-ROM | disk | FTP | other *** search
- //• ——————————————————————————————•••———————————————————————————————•//
- //• Another old source project, brought back from the dead by •//
- //• Kenneth A Long, at itty bitty bytes(tm)! •//
- //• ——————————————————————————————•••———————————————————————————————•//
-
- // 18-Jun-88 14:52:30-MDT,16523;000000000001
- // Return-Path: <u-lchoqu%sunset@cs.utah.edu>
- // Received: from cs.utah.edu by SIMTEL20.ARPA with TCP; Sat, 18 Jun 88 14:52:07 MDT
- // Received: by cs.utah.edu (5.54/utah-2.0-cs)
- // id AA22823; Sat, 18 Jun 88 14:52:05 MDT
- // Received: by sunset.utah.edu (5.54/utah-2.0-leaf)
- // id AA24896; Sat, 18 Jun 88 14:52:01 MDT
- // Date: Sat, 18 Jun 88 14:52:01 MDT
- // From: u-lchoqu%sunset@cs.utah.edu (Lee Choquette)
- // Message-Id: <8806182052.AA24896@sunset.utah.edu>
- // To: rthum@simtel20.arpa
- // Subject: pong.c
-
- /* pong.c
- The classic game of pong in Megamax C for the Mac.
- Thanks to MacTutor (Vol 1, No. 5 April 1985 page 39) for
- animation techniques. If you are reading this and don't
- subscribe to MacTutor, consider it. No resource file is
- needed. This program, source and object, is in the
- public domain and not for sale.
-
- Author: David L. O'Connor, 370 Eden St. Buffalo, N.Y.
- 14220. (716) 828-0898. CIS - 70265,1172
- Date : July, 1985 Version 2
- */
-
- #include <stdio.h>
- #include <sound.h>
-
- /* the game directions */
- #define STOPPED 0
- #define UP 1
- #define DOWN 2
- #define LEFT 3
- #define RIGHT 4
- #define UP_LEFT 5
- #define UP_RIGHT 6
- #define DOWN_LEFT 7
- #define DOWN_RIGHT 8
-
- /* paddle + ball dimensions */
- #define PADWIDTH 10
- #define PADLENGTH 45
- #define PADINSET 10
- #define BALLWIDTH 9
- #define BALLLENGTH 9
-
- #define BALLSPEED 7
- #define PADDLESPEED 9
- #define HIGHSCORE 21
-
- /* the menu ids */
- #define appleID 128
- #define fileID 129
- #define editID 130
- #define skillID 131
- #define soundID 132
-
- /* from the MAC's standard pattern list */
- #define PAD_PAT qd.dkGray //((*pat_handle)->pat_list[6])
- #define WALL_PAT qd.gray //((*pat_handle)->pat_list[4])
-
- typedef struct{
- short pat_cnt;
- Pattern pat_list[38];
- } sys_patterns;
-
- typedef struct {
- Rect r;
- short dir;
- short speed;
- short score;
- } paddle;
-
- typedef struct {
- RgnHandle rgn;
- RgnHandle oldRgn;
- RgnHandle unRgn;
- short dir;
- short speed;
- short on;
- } target;
-
- typedef struct {
- short mode;
- Tone triplet[1];
- } bleep_tag;
-
- typedef struct {
- short mode;
- Tone triplet[2];
- } blat_tag;
-
- static bleep_tag bleep_buf;
- static blat_tag blat_buf;
- static paddle l_paddle, r_paddle;
- static target ball;
- static sys_patterns **pat_handle;
- static WindowPtr gameWindow, which_window, aboutWindow;
- static WindowRecord winStorage;
- static Rect r, r2, dragRect, top_wall, bottom_wall;
- static EventRecord gameEvent;
- static MenuHandle gameMenu[5];
- static char menuTitle[1];
- static short skill_level, done, paused, last_won, volleys, sound_on;
- static char title[] = {
- "\pLeft 00 - Mac Pong - Right 00"
- //• 12345678901234567890123456789
- };
-
- main()
- {
- SetUp();
- HideCursor ();
-
- while (! done)
- {
- Handle_Events();
- Play_Pong();
- }
- FlushEvents(everyEvent, 0);
- // StopSound();
- ExitToShell();
- }
-
- SetUp()
- {
- done = 0;
- skill_level = 2;
- sound_on = 1;
- last_won = RIGHT;
- InitGraf(&qd.thePort);
- InitFonts();
- InitWindows();
- TEInit();
- InitDialogs(0);
- InitCursor();
- InitSounds();
-
- pat_handle = (sys_patterns**) GetResource('PAT#', 0);
-
- FlushEvents(everyEvent, 0);
-
- SetRect(&r, 4, 40, 508, 338);
- SetRect(&dragRect, 4, 24, r.right - 4, r.bottom - 4);
-
- // gameWindow = NewWindow(&winStorage,
- // &r, "\pLeft 00 MAC_Pong Right 00",
- // 1, rDocProc, (WindowPtr)-1L, 0, 0L);
-
- gameWindow = NewWindow(&winStorage, &r, (StringPtr) title, 1, rDocProc, (WindowPtr)-1L, 0, 0L);
-
- SetPort(gameWindow);
- Build_Menus();
- ShowCursor();
- Create_L_Paddle();
- Create_R_Paddle();
- Create_Walls();
- Create_Ball();
- Init_Game();
- }
-
- /* pretty much straight from SAMP in I.M. */
- Handle_Events()
- {
- SystemTask();
- if (GetNextEvent(everyEvent, &gameEvent))
- {
- switch (gameEvent.what)
- {
- case mouseDown:
- ShowCursor ();
- switch (FindWindow(gameEvent.where, &which_window))
- {
- case inMenuBar:
- DoCommand(MenuSelect(gameEvent.where));
- break;
- case inSysWindow:
- SystemClick(&gameEvent, which_window);
- break;
- case inDrag:
- DragWindow(which_window, gameEvent.where, &dragRect);
- break;
- case inContent:
- if (which_window != FrontWindow())
- SelectWindow(which_window);
- break;
- }
- break;
-
- case keyDown:
- case autoKey:
- if ((gameEvent.modifiers & cmdKey) != 0)
- {
- // AdjustMenus();
- DoCommand(MenuKey((char) (gameEvent.message & charCodeMask)));
- }
- break;
-
- case activateEvt:
- if (gameEvent.modifiers & activeFlag)
- Disable_Edit_Menu();
- else
- Enable_Edit_Menu();
- break;
-
- case updateEvt:
- SetPort(gameWindow);
- BeginUpdate(gameWindow);
- FillRect(&l_paddle.r, &PAD_PAT);
- FillRect(&r_paddle.r, &PAD_PAT);
- FillRect(&top_wall, &WALL_PAT);
- FillRect(&bottom_wall, &WALL_PAT);
- if (ball.on)
- PaintRgn(ball.rgn);
- EndUpdate(gameWindow);
- break;
- }
- }
- }
-
- Play_Pong()
- {
- if ( (! paused) && (l_paddle.score < HIGHSCORE && r_paddle.score < HIGHSCORE))
- {
- if (! ball.on)
- Serve_Ball();
- Check_Status();
- Move_Left_Paddle();
- Move_Right_Paddle();
- Move_Ball();
- }
- }
-
- InitSounds()
- {
- bleep_buf.mode = swMode;
- bleep_buf.triplet[0].count = 1000;
- bleep_buf.triplet[0].amplitude = 255;
- bleep_buf.triplet[0].duration = 5;
- blat_buf.mode = swMode;
- blat_buf.triplet[0].count = 1000;
- blat_buf.triplet[0].amplitude = 255;
- blat_buf.triplet[0].duration = 5;
- blat_buf.triplet[1].count = 3000;
- blat_buf.triplet[1].amplitude = 255;
- blat_buf.triplet[1].duration = 10;
- }
-
- Build_Menus()
- {
- register short i;
-
- InitMenus();
- gameMenu[0] = NewMenu(appleID, "\p\024");
- gameMenu[1] = NewMenu(fileID, "\pFile");
- gameMenu[2] = NewMenu(editID, "\pEdit");
- gameMenu[3] = NewMenu(skillID, "\pSkill");
- gameMenu[4] = NewMenu(soundID, "\pSound");
- AppendMenu(gameMenu[0],"\pAbout \"Pong\"");
- AddResMenu(gameMenu[0],'DRVR');
- AppendMenu(gameMenu[1],"\pPause/P;Restart/R;Quit/Q");
- AppendMenu(gameMenu[2],"\p(Undo/Z;(-;(Cut/X;(Copy/C;(Paste/V;(Clear");
- AppendMenu(gameMenu[3],"\pBeginner/B;Novice/N;Normal;Expert/E");
- AppendMenu(gameMenu[4],"\pSound Off/S");
- for(i = 0; i < 5; i++)
- InsertMenu(gameMenu[i], 0);
- CheckItem(gameMenu[3], skill_level, 1);
- DrawMenuBar();
- }
-
- Disable_Edit_Menu()
- {
- DisableItem(gameMenu[2], 1);
- DisableItem(gameMenu[2], 3);
- DisableItem(gameMenu[2], 4);
- DisableItem(gameMenu[2], 5);
- DisableItem(gameMenu[2], 6);
- }
-
- Enable_Edit_Menu()
- {
- EnableItem(gameMenu[2], 1);
- EnableItem(gameMenu[2], 3);
- EnableItem(gameMenu[2], 4);
- EnableItem(gameMenu[2], 5);
- EnableItem(gameMenu[2], 6);
- }
-
- DoCommand (long menu_selection)
- {
- register short the_item;
- static char name[256];
-
- the_item = LoWord(menu_selection);
- switch (HiWord(menu_selection))
- {
- case appleID:
- GetItem(gameMenu[0], the_item, (StringPtr) name);
- OpenDeskAcc((StringPtr) name);
- SetPort(gameWindow);
- break;
-
- case editID:
- SystemEdit(the_item - 1);
- break;
-
- case fileID:
- switch (the_item)
- {
- case 1:
- if (paused)
- {
- paused = 0;
- SetItem(gameMenu[1], 1, "\pPause");
- ShowCursor ();
- }
- else
- {
- paused = 1;
- SetItem(gameMenu[1], 1, "\pContinue");
- HideCursor ();
- }
- break;
-
- case 2:
- Init_Game();
- HideCursor ();
- break;
-
- case 3:
- done = 1;
- break;
- }
- break;
-
- case skillID:
- CheckItem(gameMenu[3], skill_level, 0);
- skill_level = the_item;
- CheckItem(gameMenu[3], skill_level, 1);
- HideCursor ();
- break;
-
- case soundID:
- if (sound_on)
- {
- sound_on = 0;
- SetItem(gameMenu[4], 1, "\pSound On");
- }
- else
- {
- sound_on = 1;
- SetItem(gameMenu[4], 1, "\pSound Off");
- }
- HideCursor ();
- break;
- }
- HiliteMenu(0);
- }
-
- Create_L_Paddle()
- {
- l_paddle.dir = STOPPED;
- l_paddle.speed = PADDLESPEED;
- l_paddle.score = 0;
- SetRect (&l_paddle.r,
- winStorage.port.portRect.left + PADINSET,
- winStorage.port.portRect.top + PADINSET,
- winStorage.port.portRect.left + PADINSET + PADWIDTH,
- winStorage.port.portRect.top + PADINSET + PADLENGTH);
- FillRect(&l_paddle.r, &PAD_PAT);
- }
-
- Create_R_Paddle()
- {
- r_paddle.dir = STOPPED;
- r_paddle.speed = PADDLESPEED;
- r_paddle.score = 0;
- SetRect (&r_paddle.r,
- winStorage.port.portRect.right - PADWIDTH - PADINSET,
- winStorage.port.portRect.top + PADINSET,
- winStorage.port.portRect.right - PADWIDTH - PADINSET + PADWIDTH,
- winStorage.port.portRect.top + PADINSET + PADLENGTH);
- FillRect(&r_paddle.r, &PAD_PAT);
- }
-
- Create_Walls()
- {
- SetRect(&top_wall,
- winStorage.port.portRect.left + 20,
- winStorage.port.portRect.top + 5,
- winStorage.port.portRect.right - 20,
- winStorage.port.portRect.top + 20);
- FillRect(&top_wall, &WALL_PAT);
- SetRect(&bottom_wall,
- winStorage.port.portRect.left + 20,
- winStorage.port.portRect.bottom - 20,
- winStorage.port.portRect.right - 20,
- winStorage.port.portRect.bottom - 5);
- FillRect(&bottom_wall, &WALL_PAT);
- }
-
- Create_Ball()
- {
- ball.rgn = NewRgn();
- ball.oldRgn = NewRgn();
- ball.unRgn = NewRgn();
- ball.dir = LEFT;
- ball.speed = BALLSPEED;
- SetRect (&r, 250, 150, 250 + BALLWIDTH, 150 + BALLLENGTH);
- OpenRgn();
- FrameOval(&r);
- CloseRgn(ball.rgn);
- }
-
- Serve_Ball()
- {
- register i;
-
- OffsetRgn(ball.rgn, 250 - ((**ball.rgn).rgnBBox.right),
- 150 - ((**ball.rgn).rgnBBox.top) );
- for (i = 0; i < 250; i++)
- {
- Check_Status();
- Move_Right_Paddle();
- Move_Left_Paddle();
- Move_Ball();
- }
- ball.dir = (last_won == RIGHT) ? LEFT: RIGHT;
- ball.speed = BALLSPEED;
- ball.on = 1;
- PaintRgn(ball.rgn);
- Bleep();
- }
-
- /* someone scored a point */
- Kill_Ball()
- {
- ball.on = volleys = 0;
- CopyRgn(ball.rgn, ball.unRgn);
- EraseRgn(ball.rgn);
- Recover_From_Collision();
- Blat();
- Display_Score();
- }
-
- Init_Game()
- {
- l_paddle.score = r_paddle.score = 0;
- ball.speed = BALLSPEED;
- Kill_Ball();
- }
-
- /* check for bounces, direction changes, scoring, etc */
- Check_Status()
- {
- static Rect *ball_r;
-
- register ball_top = (**ball.rgn).rgnBBox.top;
- register ball_bottom = (**ball.rgn).rgnBBox.bottom;
- register ball_left = (**ball.rgn).rgnBBox.left;
- register ball_right = (**ball.rgn).rgnBBox.right;
-
- ball_r = &((**ball.rgn).rgnBBox);
-
- /* make it a little harder as time goes by */
- if (volleys > 35)
- ball.speed = BALLSPEED + 6;
- else if (volleys > 30)
- ball.speed = BALLSPEED + 5;
- else if (volleys > 25)
- ball.speed = BALLSPEED + 4;
- else if (volleys > 20)
- ball.speed = BALLSPEED + 3;
- else if (volleys > 15)
- ball.speed = BALLSPEED + 2;
- else if (volleys > 10)
- ball.speed = BALLSPEED + 1;
-
- r_paddle.speed = ball.speed + 2;
-
- /* the right paddle tries to track the ball */
- if ( (ball_right > 250) &&
- (ball.dir == UP_RIGHT || ball.dir == DOWN_RIGHT ||
- ball.dir == RIGHT) ){
- if (ball_top + Handicap() < r_paddle.r.top)
- r_paddle.dir = UP;
- else if (ball_bottom - Handicap() > r_paddle.r.bottom)
- r_paddle.dir = DOWN;
- else
- r_paddle.dir = STOPPED;
- }
- else
- r_paddle.dir = STOPPED;
-
- /* the ball and the left boundry */
- if (ball_left < l_paddle.r.right ){
- if (SectRect(ball_r, &l_paddle.r, &r))
- {
- volleys++;
- Bleep();
- if (ball_top <= l_paddle.r.top + 15)
- ball.dir = UP_RIGHT;
- else if (ball_top > l_paddle.r.top + 15 && ball_bottom < l_paddle.r.top + 30)
- ball.dir = RIGHT;
- else
- ball.dir = DOWN_RIGHT;
- }
- else{
- last_won = RIGHT;
- r_paddle.score++;
- Kill_Ball();
- }
- return;
- }
-
- /* the ball and the right boundry */
- if (ball_right > r_paddle.r.left){
- if (SectRect(ball_r, &r_paddle.r, &r)){
- volleys++;
- Bleep();
- if (ball_top <= r_paddle.r.top + 15)
- ball.dir = UP_LEFT;
- else if (ball_top > r_paddle.r.top + 15 && ball_bottom < r_paddle.r.top + 30)
- ball.dir = LEFT;
- else
- ball.dir = DOWN_LEFT;
- }
- else{
- last_won = LEFT;
- l_paddle.score++;
- Kill_Ball();
- }
- return;
- }
-
- /* the ball and the top wall */
- if (ball_top < top_wall.bottom){
- if (ball.dir == UP_LEFT)
- ball.dir = DOWN_LEFT;
- else if (ball.dir == UP_RIGHT)
- ball.dir = DOWN_RIGHT;
- Bleep();
- return;
- }
-
- /* the ball and the bottom wall */
- if (ball_bottom > bottom_wall.top){
- if (ball.dir == DOWN_LEFT)
- ball.dir = UP_LEFT;
- else if (ball.dir == DOWN_RIGHT)
- ball.dir = UP_RIGHT;
- Bleep();
- return;
- }
- }
-
- /* the ball eats the walls and paddles */
- Recover_From_Collision()
- {
- register Rect *rp = &((**ball.unRgn).rgnBBox);
-
- if (SectRect(rp, &top_wall, &r))
- FillRect(&r, &WALL_PAT);
- else if (SectRect(rp, &bottom_wall, &r))
- FillRect(&r,&WALL_PAT);
- if (SectRect(rp, &l_paddle.r, &r))
- FillRect(&r, &PAD_PAT);
- else if (SectRect(rp, &r_paddle.r, &r))
- FillRect(&r, &PAD_PAT);
- }
-
- Move_Left_Paddle()
- {
- static Point mouseLoc;
- register short newTop, newBottom;
-
- GetMouse(&mouseLoc);
- if (mouseLoc.v != l_paddle.r.top)
- {
- r.left = l_paddle.r.left;
- r.right = l_paddle.r.right;
- if (mouseLoc.v <= winStorage.port.portRect.top)
- {
- newTop = winStorage.port.portRect.top;
- newBottom = newTop + PADLENGTH;
- }
- else if (mouseLoc.v + PADLENGTH >= winStorage.port.portRect.bottom){
- newBottom = winStorage.port.portRect.bottom;
- newTop = newBottom - PADLENGTH;
- }
- else{
- newTop = mouseLoc.v;
- newBottom = newTop + PADLENGTH;
- }
- if (newTop > l_paddle.r.top)
- {
- r.top = l_paddle.r.top;
- r.bottom = (newTop > l_paddle.r.bottom) ? l_paddle.r.bottom: newTop;
- }
- else if (newTop < l_paddle.r.top){
- r.bottom = l_paddle.r.bottom;
- r.top = (newBottom < l_paddle.r.top) ? l_paddle.r.top: newBottom;
- }
- l_paddle.r.top = newTop;
- l_paddle.r.bottom = newBottom;
- EraseRect(&r);
- FillRect(&l_paddle.r,&PAD_PAT);
- }
- else
- FillRect(&l_paddle.r, &PAD_PAT);
- }
-
- Move_Right_Paddle()
- {
- if (r_paddle.dir == STOPPED)
- FillRect(&r_paddle.r, &PAD_PAT);
- else{
- r.left = r_paddle.r.left;
- r.right = r_paddle.r.right;
- switch (r_paddle.dir)
- {
- case UP:
- r.bottom = r_paddle.r.bottom;
- r_paddle.r.top -= r_paddle.speed;
- r_paddle.r.bottom -= r_paddle.speed;
- r.top = r_paddle.r.bottom;
- break;
- case DOWN:
- r.top = r_paddle.r.top;
- r_paddle.r.top += r_paddle.speed;
- r_paddle.r.bottom += r_paddle.speed;
- r.bottom = r_paddle.r.top;
- break;
- }
- EraseRect(&r);
- FillRect(&r_paddle.r, &PAD_PAT);
- }
- }
-
- Move_Ball()
- {
- if (ball.on){
- CopyRgn(ball.rgn, ball.oldRgn);
- switch (ball.dir)
- {
- case LEFT:
- OffsetRgn(ball.rgn, -ball.speed, 0);
- break;
- case RIGHT:
- OffsetRgn(ball.rgn, ball.speed, 0);
- break;
- case UP_LEFT:
- OffsetRgn(ball.rgn, -ball.speed, -ball.speed);
- break;
- case UP_RIGHT:
- OffsetRgn(ball.rgn, ball.speed, -ball.speed);
- break;
- case DOWN_LEFT:
- OffsetRgn(ball.rgn, -ball.speed, ball.speed);
- break;
- case DOWN_RIGHT:
- OffsetRgn(ball.rgn, ball.speed, ball.speed);
- break;
- }
- UnionRgn(ball.rgn, ball.oldRgn, ball.unRgn);
- DiffRgn(ball.unRgn, ball.rgn, ball.unRgn);
- EraseRgn(ball.unRgn);
- PaintRgn(ball.rgn);
- Recover_From_Collision();
- }
- }
-
- Display_Score()
- {
- static long i;
-
- if (l_paddle.score < 10)
- {
- title[6] = '0';
- i = l_paddle.score;
- NumToString(i, ((StringPtr) title + 5));
- }
- else{
- i = l_paddle.score;
- NumToString(i, ((StringPtr) title + 6));
- }
- if (r_paddle.score < 10)
- {
- title[28] = '0';
- i = r_paddle.score;
- NumToString(i, ((StringPtr) title + 27));
- }
- else
- {
- i = r_paddle.score;
- NumToString(i, ((StringPtr) title + 27));
- }
- /* NumToString inserts a '\0' we don't need */
- *(title + 5) = ' ';
- *(title + 27) = ' ';
- SetWTitle(gameWindow, (StringPtr) title);
- }
-
- Bleep()
- {
- if (sound_on)
- {;
- // if (! SoundDone())
- // StopSound();
- // StartSound((Ptr) &bleep_buf, (long) sizeof(bleep_buf), 0L);
- }
- }
-
- Blat()
- {
- if (sound_on)
- {;
- // if (! SoundDone())
- // StopSound();
- // StartSound((Ptr) &blat_buf, (long) sizeof(blat_buf), 0L);
- }
- }
-
- /* Every so often, let the Mac's paddle fail to track the ball until
- the ball has passed it by a certain amount.
- This is the heart of a satisfying game. */
- short Handicap()
- {
- register mac_skill;
-
- switch(skill_level)
- {
- case 1:
- mac_skill = 2;
- break;
-
- case 2:
- mac_skill = 8;
- break;
- case 3:
- mac_skill = 27;
- break;
-
- case 4:
- mac_skill = 64;
- break;
-
- default:
- mac_skill = 2;
- break;
- }
- return ((Random() % mac_skill) == 0) ? 5: 0;
- }
-
-